package nl.infodation.emr.pricingservice.valuesimporter;

import java.io.File;
import java.util.Date;
import java.util.List;

import nl.infodation.emr.pricingservice.controller.ControllerFactory;
import nl.infodation.emr.pricingservice.entity.LanguageSystem;
import nl.infodation.emr.pricingservice.entity.Role;
import nl.infodation.emr.pricingservice.entity.SystemValue;
import nl.infodation.emr.pricingservice.entity.SystemValue.TableName;
import nl.infodation.emr.pricingservice.entity.SystemValueRef;
import nl.infodation.emr.pricingservice.entity.SystemValueRole;
import nl.infodation.emr.pricingservice.exception.RmeException;
import nl.infodation.emr.utility.Constants;
import nl.infodation.emr.utility.StringUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.data.util.BeanItem;

@SuppressWarnings("rawtypes")
public class ValuesReader {
	
	static private final Logger LOG = LoggerFactory.getLogger(ValuesReader.class);
	
	public boolean importValues(File file) {
		boolean imported = false; 
		try {
	        final CSVFileReader reader = new CSVFileReader(file);
			CSVFile csvFile = reader.parseFile();
			
			final CSVLine[] csvLineList = csvFile.getLines();
			int linenumber = 0;
			for (CSVLine csvLine : csvLineList) {
				linenumber++;
				if (linenumber == 1) { // ignore first line
					continue;
				}
				
				final Object objects = csvLine.getElementAt(0);
				if (objects == null || ((String)objects).length() == 0) {
					continue;
				}
				
				importCsvLineToDatabase(csvLine);
			}
			imported = true;
		} catch (RmeException e) {
			LOG.error("Import file failed!");
		}
		return imported;
	}
	
    private void importCsvLineToDatabase(CSVLine csvLine) {
		final String[] elements = getElementsFromCsvLine(csvLine);
		importToTables(elements);
    }
    
    private void importToTables(String[] elements) {
    	Role role = getRoleFromBusinessLineElement(elements[0]);
    	TableName tableName = getTableNameFromTableElement(elements[1]);
    	String code = elements[2];
    	LanguageSystem languageSystem = getLanguageSystemFromLanguageElement(elements[3]);
    	String label = elements[4];
    	boolean actived = elements.length > 5 && elements[5].equals("1") ? true : false;
    	
    	SystemValue systemValue = importSystemValue(code, tableName);
    	importSystemValueRef(systemValue, label, languageSystem);
    	importSystemValueRole(systemValue, role, actived);
	}
    
	private TableName getTableNameFromTableElement(String tableElement) {
		String id = tableElement.replace(' ', '_').toUpperCase();
		return TableName.parse(id);
	}

	private void importSystemValueRole(SystemValue systemValue, Role role,
			boolean actived) {
		SystemValueRole systemValueRole = new SystemValueRole();
		systemValueRole.setSystemValue(systemValue);
		systemValueRole.setRole(role);
		systemValueRole.setActived(actived);
		if (actived) {
			systemValueRole.setValidFrom(new Date());
		} else {
			systemValueRole.setValidTo(new Date());
		}
		saveSystemValueRole(systemValueRole);
	}

	private void importSystemValueRef(SystemValue systemValue, String label,
			LanguageSystem languageSystem) {
		SystemValueRef systemValueRef = new SystemValueRef();
		systemValueRef.setSystemValue(systemValue);
		systemValueRef.setLabel(label);
		systemValueRef.setLanguageSystem(languageSystem);
		saveSystemValueRef(systemValueRef);
	}

	private SystemValue importSystemValue(String code, TableName tableName) {
		SystemValue systemValue = new SystemValue();
		systemValue.setSystemCode(code);
		systemValue.setSystemName(tableName);
		saveSystemValue(systemValue);
		return systemValue;
	}

	private void saveSystemValueRole(SystemValueRole systemValueRole) {
		Integer id = getIdBySystemValueRoleSearchItem(systemValueRole);
		systemValueRole.setId(id);
		ControllerFactory.getSystemValueRoleController().saveObject(systemValueRole);
	}
	
	private void saveSystemValueRef(SystemValueRef systemValueRef) {
		Integer id = getIdBySystemValueRefSearchItem(systemValueRef);
		systemValueRef.setSystemValueRefId(id);
		ControllerFactory.getSystemValueRefController().saveObject(systemValueRef);
	}
	
	private void saveSystemValue(SystemValue systemValue) {
		Integer id = getIdBySystemValueSearchItem(systemValue);
		systemValue.setSystemValueId(id);
		ControllerFactory.getSystemValueController().saveObject(systemValue);
	}

	private Integer getIdBySystemValueRoleSearchItem(SystemValueRole searchItem) {
		List<BeanItem> beans = ControllerFactory.getSystemValueRoleController().getPaginationByCriteria(searchItem, 1, Integer.MAX_VALUE);
		if (null == beans || beans.isEmpty()) {
			return null;
		}
		SystemValueRole obj = (SystemValueRole)beans.get(0).getBean();
		return obj.getId();
	}
	
	private Integer getIdBySystemValueRefSearchItem(SystemValueRef searchItem) {
		List<BeanItem> beans = ControllerFactory.getSystemValueRefController().getPaginationByCriteria(searchItem, 1, Integer.MAX_VALUE);
		if (null == beans || beans.isEmpty()) {
			return null;
		}
		SystemValueRef obj = (SystemValueRef)beans.get(0).getBean();
		return obj.getSystemValueRefId();
	}
	
	private Integer getIdBySystemValueSearchItem(SystemValue searchItem) {
		List<BeanItem> beans = ControllerFactory.getSystemValueController().getPaginationByCriteria(searchItem, 1, Integer.MAX_VALUE);
		if (null == beans || beans.isEmpty()) {
			return null;
		}
		SystemValue obj = (SystemValue)beans.get(0).getBean();
		return obj.getSystemValueId();
	}
	
	private LanguageSystem getLanguageSystemFromLanguageElement(String languageElement) {
		if (StringUtil.isEmptyOrBlank(languageElement)) {
			return (LanguageSystem)ControllerFactory.getLanguageSystemController().getObjectById(Constants.LANGUAGE_SYSTEM_ID_DEFAULT);
		}
		return getLanguageSystemByCode(languageElement);
	}
	
	private Role getRoleFromBusinessLineElement(String csvBusinessLine) {
		Integer roleId = null;
		if (csvBusinessLine.equals("DML")) {
			roleId = Constants.PROVEA_ROLE_ID;
			
		} else if (csvBusinessLine.equals("AFM")) {
			roleId = Constants.AFM_ROLE_ID;
		}
		
		return (Role)ControllerFactory.getRoleController().getObjectById(roleId);
	}

	private LanguageSystem getLanguageSystemByCode(String languageSystemCode) {
		LanguageSystem languageSystem = null;
		
		LanguageSystem searchItem = new LanguageSystem();
		searchItem.setLanguageSystemCode(languageSystemCode.toLowerCase());
		List<BeanItem> items = ControllerFactory.getLanguageSystemController().getPaginationByCriteria(searchItem, 1, Integer.MAX_VALUE);
		if (null != items && !items.isEmpty()) {
			LanguageSystem langSystem = (LanguageSystem)(items.get(0).getBean());
			languageSystem = langSystem;
		}
		
		return languageSystem;
	}
	
    private String[] getElementsFromCsvLine(CSVLine csvLine) {
    	final StringBuffer stringToSplit = new StringBuffer("");
		for (Object element : csvLine.getElements()) {
			stringToSplit.append(String.valueOf(element));
		}
		return stringToSplit.toString().split(";");
	}
    
}
